package hkust.cse.calendar.gui;

import hkust.cse.calendar.apptstorage.ApptStorageControllerImpl;
import hkust.cse.calendar.apptstorage.ApptStorageNullImpl;
import hkust.cse.calendar.unit.User;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;


public class LoginDialog extends JFrame implements ActionListener
{
	private JTextField userName;
	private JPasswordField password;
	private JButton button;
	private JButton closeButton;
	private JButton signupButton;

	public LoginDialog()		// Create a dialog to log in
	{

		setTitle("Log in");

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});


		Container contentPane;
		contentPane = getContentPane();

		JPanel top = new JPanel();
		top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS));

		JPanel messPanel = new JPanel();
		messPanel.add(new JLabel("Please input your user name and password to log in."));
		top.add(messPanel);

		JPanel namePanel = new JPanel();
		namePanel.add(new JLabel("User Name:"));
		userName = new JTextField(15);
		namePanel.add(userName);
		top.add(namePanel);

		JPanel pwPanel = new JPanel();
		pwPanel.add(new JLabel("Password:  "));
		password = new JPasswordField(15);
		pwPanel.add(password);
		top.add(pwPanel);

		JPanel signupPanel = new JPanel();
		signupPanel.add(new JLabel("If you don't have an account, please sign up:"));
		signupButton = new JButton("Sign up now");
		signupButton.addActionListener(this);
		signupPanel.add(signupButton);
		top.add(signupPanel);

		contentPane.add("North", top);

		JPanel butPanel = new JPanel();
		butPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

		button = new JButton("Log in (No user name and password required)");
		button.addActionListener(this);
		butPanel.add(button);

		closeButton = new JButton("Close program");
		closeButton.addActionListener(this);
		butPanel.add(closeButton);

		contentPane.add("South", butPanel);

		pack();
		setLocationRelativeTo(null);
		setVisible(true);	

	}


	public void actionPerformed(ActionEvent e) {

		// TODO Auto-generated method stub
		if(e.getSource() == button)
		{
			String username = userName.getText();	// convert the JTextField to string
			char[] p = password.getPassword();
			String Password = new String(p);	// convert the JPassword to string
			if(ValidString(username) && ValidString(Password)){

				// When the button is clicked, check the user name and password, and try to log the user in
				User user = new User( username , Password);
				if(user.login(username, Password)){	// if the user exists
					CalGrid grid = new CalGrid(new ApptStorageControllerImpl(new ApptStorageNullImpl(user)));
					setVisible( false );
				}else{
					JOptionPane.showMessageDialog(null,
							"User and password do not match !",
							"ERROR",
							JOptionPane.WARNING_MESSAGE);
				}
			}else{
				JOptionPane.showMessageDialog(null,
						"INVALID INPUT for username and password !",
						"ERROR",
						JOptionPane.WARNING_MESSAGE);
			}
		}
		else if(e.getSource() == signupButton)
		{
			boolean invalidInput = true;
			while(invalidInput == true){
				JTextField field1 = new JTextField();  // Username
				JPasswordField field2 = new JPasswordField(); 	//Password
				JPasswordField field3 = new JPasswordField();  	// the Confirmed Password


				Object[] message = {  
						"Username:", field1,  
						"Password:", field2,  
						"Confirmed Password:", field3,  

				};  
				int option = JOptionPane.showConfirmDialog(null, message, "Enter all your information ", JOptionPane.OK_CANCEL_OPTION);  
				if(ValidString(field1.getText()) && ValidString(field2.getText()) && ValidString(field3.getText())){
					if (option == JOptionPane.OK_OPTION)  
					{  
						User tempUser = new User(field1.getText() , field2.getText());
						if( (field2.getText().equals(field3.getText())) == false){
							JOptionPane.showMessageDialog(null,
									"Password and Confirmed Password do not match!",
									"ERROR",
									JOptionPane.WARNING_MESSAGE);
						}else if(tempUser.UsernameExisted(field1.getText())){
							JOptionPane.showMessageDialog(null,
									"The Username " + field1.getText() + " already existed , Please use another account!",
									"ERROR",
									JOptionPane.WARNING_MESSAGE);
						}else{	// all ERROR cases pass , then create the user
							tempUser.createNewAccount(field1.getText(), field2.getText());
							invalidInput = false;	// the input is true
						}
					}  
				}else{
					if(option == JOptionPane.CANCEL_OPTION || option == JOptionPane.CLOSED_OPTION){

						invalidInput = false;

					}else{
						JOptionPane.showMessageDialog(null,
								"INVALID INPUT for username and password !",
								"ERROR",
								JOptionPane.WARNING_MESSAGE);
					}
				}
			}

		}
		else if(e.getSource() == closeButton)
		{
			int n = JOptionPane.showConfirmDialog(null, "Exit Program ?",
					"Confirm", JOptionPane.YES_NO_OPTION);
			if (n == JOptionPane.YES_OPTION)
				System.exit(0);			
		}
	}

	// This method checks whether a string is a valid user name or password, as they can contains only letters and numbers
	public static boolean ValidString(String s)
	{
		char[] sChar = s.toCharArray();
		if(s.length() == 0){
			return false;
		}
		for(int i = 0; i < sChar.length; i++)
		{
			int sInt = (int)sChar[i];
			if(sInt < 48 || sInt > 122)
				return false;
			if(sInt > 57 && sInt < 65)
				return false;
			if(sInt > 90 && sInt < 97)
				return false;
		}
		return true;
	}
}
